package net.lengwang.iot.middleware.network;

import net.lengwang.iot.middleware.packet.ParsedPacket;
import net.lengwang.iot.middleware.packet.response.*;
import net.lengwang.iot.middleware.utils.DataEncoder;
import net.lengwang.iot.middleware.packet.PacketType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.net.Socket;

public class CommonService implements CommonServiceInterface {

    private int sequenceNumber = 0; // 添加这一行
    private NetworkListener networkListener;

    private static final Logger logger = LoggerFactory.getLogger(NetworkListener.class);

    public CommonService(NetworkListener networkListener) {
        this.networkListener = networkListener;
    }

    @Override
    public void handlePacket(ParsedPacket parsedPacket) {
        String connectionId = parsedPacket.getConnectionId();
        // logger.info("开始处理数据包，连接ID：{}", connectionId);
        logger.info("### 网关 ID: {}, 数据包类型: {} = {}, 接收到数据包内容: {}", parsedPacket.getGatewayId(), parsedPacket.getCommand(), parsedPacket.getCommandName(), parsedPacket.getParsedData());

        if (isValidPacket(parsedPacket)) {
            try {
                byte[] response = createResponse(parsedPacket);
                // logger.info("准备发送响应，连接ID：{}", connectionId);
                sendDirectResponse(connectionId, response);
                // logger.info("向连接 {} 发送响应成功", connectionId);
            } catch (IOException e) {
                logger.error("向连接 {} 发送响应失败", connectionId, e);
            }
        } else {
            logger.warn("收到无效的数据包，来自连接 {} ", connectionId);
            logger.warn("无效数包内容: {}", parsedPacket.toString());
        }
    }

    protected void sendDirectResponse(String connectionId, byte[] response) throws IOException {
        // logger.info("尝试发送响应到连接：{}", connectionId);

        Object channel = networkListener.getConnection(connectionId);
        if (channel == null) {
            logger.error("无法找到连接 {} 的通道", connectionId);
            throw new IOException("无法找到连接通道");
        }

        // logger.info("找到连接 {} 的通道，类型：{}", connectionId, channel.getClass().getSimpleName());

        if (channel instanceof SocketChannel) {
            SocketChannel socketChannel = (SocketChannel) channel;
            if (socketChannel.isOpen()) {
                ByteBuffer buffer = ByteBuffer.wrap(response);
                while (buffer.hasRemaining()) {
                    socketChannel.write(buffer);
                }
                // logger.info("通过 SocketChannel 发送数据完成，连接ID：{}", connectionId);
                logger.info("-> 发送的数据：{}", DataEncoder.bytesToHex(response));
            } else {
                throw new IOException("SocketChannel 已关闭");
            }
        } else if (channel instanceof Socket) {
            Socket socket = (Socket) channel;
            if (!socket.isClosed()) {
                socket.getOutputStream().write(response);
                socket.getOutputStream().flush();
                // logger.info("通过 Socket 发送数据完成，连接ID：{}", connectionId);
                logger.info("-> 发送的数据：{}", DataEncoder.bytesToHex(response));
            } else {
                throw new IOException("Socket 已关闭");
            }
        } else {
            logger.error("连接 {} 的通道类型不支持：{}", connectionId, channel.getClass().getSimpleName());
            throw new IOException("不支持的连接通道类型");
        }
    }

    protected byte[] createResponse(ParsedPacket parsedPacket) {
        String command = parsedPacket.getCommand();
        // logger.info("### 数据包类型：{}", command);
        switch (command) {
            // 握手 90
            case PacketType.BEBE_GATEWAY_HANDSHAKE:
                return new HandshakeResponsePacket(parsedPacket).toByteArray();
            // 授时 91
            case PacketType.BEBE_GATEWAY_TIME_SYNC:
                return new TimeSyncResponsePacket(parsedPacket).toByteArray();
            case PacketType.BEBE_GATEWAY_STATUS_REPORT:
                return new StatusReportResponsePacket(parsedPacket).toByteArray();

                // 状态上报
                // case PacketType.BEBE_GATEWAY_STATUS_REPORT:
                // return new StatusReportResponsePacket(parsedPacket).toByteArray();
                // // 绑定
                // case PacketType.BEBE_SERVER_BINDING_DISPATCH:
                // return new BindingDispatchResponsePacket(parsedPacket).toByteArray();
            default:
                logger.error("ERR： 未找到对应的响应包类型：{}的解析方法", command);
                // TODO 待补充PacketType的反馈
                return null;
        }
    }

    public synchronized int getNextSequenceNumber() {
        if (sequenceNumber == Integer.MAX_VALUE) {
            sequenceNumber = 0;
        }
        return ++sequenceNumber;
    }

    protected boolean isValidPacket(ParsedPacket parsedPacket) {
        // 验证数据包是否有效的逻辑
        return true; // 默认认为所有包都有效，子类可以重写此方法
    }

    @Override
    public void sendResponse(String connectionId, byte[] response) {
        networkListener.sendResponse(connectionId, response);
    }
}
